/*
 * Copyright (C) 2009 Lianhaidong <lianhaidong@gmail.com>
 */

#ifndef _UTILS_SINGLE_LIST_H
#define _UTILS_SINGLE_LIST_H

#include <stdlib.h>

struct slist_node {
	struct slist_node *next;
};

struct slist {
	struct slist_node *head;
	struct slist_node *tail;
	int node_count;
};

static inline void slist_init(struct slist *sl)
{
	sl->head = NULL;
	sl->tail = NULL;
	sl->node_count = 0;
}

static inline int slist_node_count(struct slist *sl)
{
	return sl->node_count;
}

static inline void slist_insert_head(struct slist *sl, struct slist_node *sn)
{
	sn->next = sl->head;
	sl->head = sn;
	if (!sl->tail)
		sl->tail = sn;
	
	sl->node_count ++;
}

static inline void slist_insert_tail(struct slist *sl, struct slist_node *sn)
{
	if (sl->tail) {
		sl->tail->next = sn;
	} else {
		sl->head = sn;
	}
	
	sl->tail = sn;
	sl->node_count ++;
}

struct slist_node *slist_del(struct slist *sl, struct slist_node *sn);

#define slist_node_entry(ptr, type, member) \
	(type*)((unsigned long)(ptr) - (unsigned long)&((type *)0)->member)

#define slist_for_each_node(pos, sl)	\
	for (pos = sl->head; pos ; pos = pos->next)

#define slist_for_each_node_entry(pos, sl, member)	\
	for (pos = slist_node_entry(sl->head, typeof(pos), member);	\
	    &pos->member;	\
	    pos = slist_node_entry(pos->member.next, typeof(*pos), member))

#endif	/* _UTILS_SINGLE_LIST_H */

